#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import os
import sys

from dws.commons.common import check_path_valid, log
from common.util.check_utils import is_valid_id
from common.common import exter_attack
from dws.backup.cluster_backup import ClusterBackup
from dws.backup.delete_copy import DeleteCopy
from dws.commons.dws_param_parse import CopyInfoParam, DwsParamParse
from dws.commons.job_info import CopyInfo, JobInfo
from common.util.exec_utils import exec_mkdir_cmd
from dws.commons.parse_param import parse_param_with_jsonschema


def prepare_res(job_info: JobInfo):
    """
    副本删除没有前置任务，所以这里在cache仓中手动创建一下tmp目录
    """
    # 创建临时目录
    tmp_copy_dir = os.path.join(job_info.cache_path, "tmp", job_info.copy_id)
    if not check_path_valid(tmp_copy_dir):
        log.error(f"Invalid tmp dir [{tmp_copy_dir}], {job_info.log_format()}.")
        return False
    if os.path.exists(tmp_copy_dir):
        log.warn(f"Tmp dir [{tmp_copy_dir}] already exists, {job_info.log_format()}.")
        return True
    if not exec_mkdir_cmd(tmp_copy_dir):
        log.error(f"Create tmp dir [{tmp_copy_dir}], {job_info.log_format()}.")
        return False
    log.info(f"Create tmp dir [{tmp_copy_dir}] success, {job_info.log_format()}.")
    return True


@exter_attack
def do_exec(func_type, pid):
    log.info(f"Enter, pid: {pid}.")
    param = parse_param_with_jsonschema(pid)

    job_info = JobInfo(
        pid=pid,
        job_id=DwsParamParse.get_job_id(param),
        sub_job_id=DwsParamParse.get_sub_job_id(param),
        copy_id=DwsParamParse.get_job_id(param),
        usr=DwsParamParse.get_user_name(param),
        env_path=DwsParamParse.get_env_path(param))

    all_del_copies = []
    for per_copy in DwsParamParse.get_copies(param):
        vitural_param = {"job": per_copy}
        all_del_copies.append(
            CopyInfo(
                backup_key=CopyInfoParam.get_backup_key(per_copy),
                copy_id=CopyInfoParam.get_copy_id(per_copy),
                backup_tool_type=DwsParamParse.get_backup_tool_type(vitural_param),
                metadata_destination=CopyInfoParam.get_metadata_destination(per_copy),
                cache_path=DwsParamParse.get_cache_path(vitural_param),
                meta_path=DwsParamParse.get_meta_path(vitural_param),
                data_reps=DwsParamParse.get_data_reps(vitural_param)))
    if not all_del_copies:
        log.error(f"Get all delete copies failed, pid: {pid}.")
        return False
    job_info.cache_path = all_del_copies[0].cache_path
    if func_type == "delete":
        if not prepare_res(job_info):
            return False
        DeleteCopy(pid).delete_copies(job_info, all_del_copies)
        log.info(f"Delete copy finish, {job_info.log_format()}.")
        return True
    else:
        ret = ClusterBackup(pid).get_progress(job_info, True, False)
        log.info(f"Get delete progress finish, ret: {ret}, {job_info.log_format()}.")
        return ret


if __name__ == '__main__':
    if len(sys.argv) < 5:
        log.error("Param is wrong.")
        sys.exit(1)

    if not is_valid_id(sys.argv[2]):
        log.warn(f"pid is invalid")
        sys.exit(1)

    try:
        if not do_exec(sys.argv[1], sys.argv[2]):
            sys.exit(1)
    except Exception as err:
        log.error(f"Err: {err}, func_type: {sys.argv[1]}, pid: {sys.argv[2]}, job_id: {sys.argv[3]}")
        sys.exit(1)

    sys.exit(0)
